package org.dromara.nursing.service.impl;

import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.nursing.domain.bo.ElderBasicBo;
import org.dromara.nursing.domain.vo.ElderBasicVo;
import org.dromara.nursing.domain.ElderBasic;
import org.dromara.nursing.mapper.ElderBasicMapper;
import org.dromara.nursing.service.IElderBasicService;

import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 老人基础信息Service业务层处理
 *
 * @author Xue
 * @date 2025-04-01
 */
@RequiredArgsConstructor
@Service
public class ElderBasicServiceImpl implements IElderBasicService {

    // 定义角色常量
    private static final String FAMILY_ROLE_KEY = "jiashu";
    private static final String ADMIN_ROLE_KEY = "admin_ms";
    private static final String SUPER_ADMIN_ROLE_KEY = "admin";

    private final ElderBasicMapper baseMapper;
    private final org.dromara.nursing.service.IContactService contactService;

    /**
     * 查询老人基础信息
     *
     * @param elderId 主键
     * @return 老人基础信息
     */
    @Override
    public ElderBasicVo queryById(Long elderId){
        ElderBasicVo elder = baseMapper.selectVoById(elderId);

        // 基于角色的数据权限过滤
        boolean isFamilyUser = cn.dev33.satoken.stp.StpUtil.hasRole(FAMILY_ROLE_KEY);
        boolean isAdminUser = cn.dev33.satoken.stp.StpUtil.hasRole(ADMIN_ROLE_KEY) ||
                             cn.dev33.satoken.stp.StpUtil.hasRole(SUPER_ADMIN_ROLE_KEY);

        // 如果是家属用户，只能查看自己关联的老人信息
        if (isFamilyUser && !isAdminUser && elder != null) {
            Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
            if (userId != null) {
                // 检查该老人是否与当前用户关联
                boolean hasAccess = checkElderAccess(elderId, userId);
                if (!hasAccess) {
                    // 如果没有权限访问，返回null
                    return null;
                }
            }
        }

        // 照片URL由@Translation注解自动处理，不需要手动处理

        return elder;
    }

    /**
     * 检查用户是否有权限访问指定老人信息
     *
     * @param elderId 老人ID
     * @param userId 用户ID
     * @return 是否有权限
     */
    private boolean checkElderAccess(Long elderId, Long userId) {
        if (elderId == null || userId == null) {
            return false;
        }

        // 通过SQL查询该用户是否与该老人关联
        try {
            // 使用参数化查询，避免SQL注入
            LambdaQueryWrapper<ElderBasic> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ElderBasic::getElderId, elderId);
            wrapper.exists("SELECT 1 FROM ms_contact_info WHERE ms_contact_info.elder_id = ms_elder_basic.elder_id AND ms_contact_info.contact_user_id = {0}", userId);

            Long count = baseMapper.selectCount(wrapper);
            return count > 0;
        } catch (Exception e) {
            org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                .error("检查用户访问权限失败: elderId={}, userId={}", elderId, userId, e);
            return false;
        }
    }

    /**
     * 分页查询老人基础信息列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 老人基础信息分页列表
     */
    @Override
    public TableDataInfo<ElderBasicVo> queryPageList(ElderBasicBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ElderBasic> lqw = buildQueryWrapper(bo);
        Page<ElderBasicVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        // 照片URL由@Translation注解自动处理，不需要手动处理

        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的老人基础信息列表
     *
     * @param bo 查询条件
     * @return 老人基础信息列表
     */
    @Override
    public List<ElderBasicVo> queryList(ElderBasicBo bo) {
        LambdaQueryWrapper<ElderBasic> lqw = buildQueryWrapper(bo);
        List<ElderBasicVo> list = baseMapper.selectVoList(lqw);

        // 照片URL由@Translation注解自动处理，不需要手动处理

        return list;
    }

    private LambdaQueryWrapper<ElderBasic> buildQueryWrapper(ElderBasicBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ElderBasic> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getElderName()), ElderBasic::getElderName, bo.getElderName());
        lqw.eq(StringUtils.isNotBlank(bo.getIdCard()), ElderBasic::getIdCard, bo.getIdCard());
        lqw.eq(StringUtils.isNotBlank(bo.getReviewStatus()), ElderBasic::getReviewStatus, bo.getReviewStatus());

        // Add condition for roomNumberIsNull
        if (bo.getRoomNumberIsNull() != null && bo.getRoomNumberIsNull()) {
            lqw.and(wrapper -> wrapper.isNull(ElderBasic::getRoomNumber).or().eq(ElderBasic::getRoomNumber, ""));
        }

        // 基于角色的数据权限过滤
        boolean isFamilyUser = cn.dev33.satoken.stp.StpUtil.hasRole(FAMILY_ROLE_KEY);
        boolean isAdminUser = cn.dev33.satoken.stp.StpUtil.hasRole(ADMIN_ROLE_KEY) ||
                             cn.dev33.satoken.stp.StpUtil.hasRole(SUPER_ADMIN_ROLE_KEY);

        // 如果是家属用户，只能查看自己关联的老人信息
        if (isFamilyUser && !isAdminUser) {
            Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
            if (userId != null) {
                // 家属用户只能查看自己关联的老人信息
                lqw.exists("SELECT 1 FROM ms_contact_info WHERE ms_contact_info.elder_id = ms_elder_basic.elder_id AND ms_contact_info.contact_user_id = {0}", userId);

                // 家属用户只能查看已审核通过的老人信息和自己提交的待审核信息
                lqw.and(wrapper -> wrapper.eq(ElderBasic::getReviewStatus, "1")  // 已通过
                                         .or()
                                         .apply("elder_id IN (SELECT elder_id FROM ms_contact_info WHERE contact_user_id = {0})", userId));
            } else {
                // 如果无法获取用户ID，则不返回任何数据
                lqw.eq(ElderBasic::getElderId, -1);
            }
        }

        // 自定义排序逻辑：待审核(0)排在前面，然后是已审核(1)，最后是已拒绝(2)
        lqw.last("ORDER BY CASE review_status " +
                 "WHEN '0' THEN 0 " +  // 待审核排第一
                 "WHEN '1' THEN 1 " +  // 已通过排第二
                 "WHEN '2' THEN 2 " +  // 已拒绝排第三
                 "ELSE 3 END, elder_id DESC");



        return lqw;
    }

    /**
     * 新增老人基础信息
     *
     * @param bo 老人基础信息
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(ElderBasicBo bo) {
        ElderBasic add = MapstructUtils.convert(bo, ElderBasic.class);
        validEntityBeforeSave(add);

        // 基于角色的数据权限过滤
        boolean isFamilyUser = cn.dev33.satoken.stp.StpUtil.hasRole(FAMILY_ROLE_KEY);
        boolean isAdminUser = cn.dev33.satoken.stp.StpUtil.hasRole(ADMIN_ROLE_KEY) ||
                             cn.dev33.satoken.stp.StpUtil.hasRole(SUPER_ADMIN_ROLE_KEY);

        // 设置审核状态
        if (isFamilyUser && !isAdminUser) {
            // 家属用户添加的老人信息需要审核
            add.setReviewStatus("0"); // 0:待审核
        } else if (isAdminUser) {
            // 管理员添加的老人信息默认已审核通过
            add.setReviewStatus("1"); // 1:已通过
            add.setReviewedBy(org.dromara.common.satoken.utils.LoginHelper.getUsername());
            add.setReviewTime(new java.util.Date());
        } else {
            // 其他用户添加的老人信息也需要审核
            add.setReviewStatus("0"); // 0:待审核
        }

        // 新增老人信息后，自动创建联系人记录关联当前用户(如果是家属用户)
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setElderId(add.getElderId());

            // 如果是家属用户，自动创建联系人记录
            if (isFamilyUser) {
                Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
                if (userId != null) {
                    try {
                        // 使用ContactService创建联系人记录
                        boolean result = contactService.createContactForElder(add.getElderId(), add.getElderName(), userId);

                        org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                            .info("自动创建联系人记录: elderId={}, userId={}, result={}", add.getElderId(), userId, result);
                    } catch (Exception e) {
                        // 记录异常但不影响老人信息保存
                        org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                            .error("自动创建联系人记录失败", e);
                    }
                }
            }
        }
        return flag;
    }

    /**
     * 修改老人基础信息
     *
     * @param bo 老人基础信息
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(ElderBasicBo bo) {
        ElderBasic update = MapstructUtils.convert(bo, ElderBasic.class);
        validEntityBeforeSave(update);

        // 基于角色的数据权限过滤
        boolean isFamilyUser = cn.dev33.satoken.stp.StpUtil.hasRole(FAMILY_ROLE_KEY);
        boolean isAdminUser = cn.dev33.satoken.stp.StpUtil.hasRole(ADMIN_ROLE_KEY) ||
                             cn.dev33.satoken.stp.StpUtil.hasRole(SUPER_ADMIN_ROLE_KEY);

        // 如果是家属用户，检查是否有权限修改该老人信息
        if (isFamilyUser && !isAdminUser) {
            Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
            if (userId != null) {
                // 检查该老人是否与当前用户关联
                boolean hasAccess = checkElderAccess(update.getElderId(), userId);
                if (!hasAccess) {
                    // 如果没有权限访问，返回false
                    org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                        .warn("用户 {} 尝试修改非关联老人 {} 的信息", userId, update.getElderId());
                    return false;
                }
            }
        }

        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ElderBasic entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除老人基础信息信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }

        // 基于角色的数据权限过滤
        boolean isFamilyUser = cn.dev33.satoken.stp.StpUtil.hasRole(FAMILY_ROLE_KEY);
        boolean isAdminUser = cn.dev33.satoken.stp.StpUtil.hasRole(ADMIN_ROLE_KEY) ||
                             cn.dev33.satoken.stp.StpUtil.hasRole(SUPER_ADMIN_ROLE_KEY);

        // 如果是家属用户，检查是否有权限删除这些老人信息
        if (isFamilyUser && !isAdminUser) {
            Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
            if (userId != null) {
                // 检查这些老人是否都与当前用户关联
                for (Long elderId : ids) {
                    boolean hasAccess = checkElderAccess(elderId, userId);
                    if (!hasAccess) {
                        // 如果有一个没有权限访问，返回false
                        org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                            .warn("用户 {} 尝试删除非关联老人 {} 的信息", userId, elderId);
                        return false;
                    }
                }
            }
        }

        return baseMapper.deleteByIds(ids) > 0;
    }



    /**
     * 查询所有老人（用于联系人验证，不进行权限过滤）
     *
     * @param name 老人姓名
     * @return 老人列表
     */
    @Override
    public List<ElderBasicVo> queryAllForVerification(String name) {
        LambdaQueryWrapper<ElderBasic> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(name), ElderBasic::getElderName, name);
        // 按照ID降序排序，确保最新添加的老人排在前面
        lqw.orderByDesc(ElderBasic::getElderId);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 验证老人身份证号（不进行权限过滤）
     *
     * @param elderId 老人ID
     * @param idCard 身份证号
     * @return 验证结果
     */
    @Override
    public Boolean verifyIdCardWithoutPermissionCheck(Long elderId, String idCard) {
        try {
            if (elderId == null || idCard == null) {
                return false;
            }

            // 直接查询数据库，不进行权限过滤
            LambdaQueryWrapper<ElderBasic> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(ElderBasic::getElderId, elderId);
            ElderBasic elder = baseMapper.selectOne(wrapper);

            // 验证身份证号是否匹配
            return elder != null && idCard.equals(elder.getIdCard());
        } catch (Exception e) {
            // 记录异常
            org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                .error("验证老人身份证号失败: elderId={}, idCard={}", elderId, idCard, e);
            return false;
        }
    }

    /**
     * 审核老人基础信息
     *
     * @param elderId 老人ID
     * @param reviewStatus 审核状态(1:通过 2:拒绝)
     * @return 是否审核成功
     */
    @Override
    public Boolean reviewElderBasic(Long elderId, String reviewStatus) {
        try {
            if (elderId == null || StringUtils.isEmpty(reviewStatus)) {
                org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                    .error("审核参数不完整: elderId={}, reviewStatus={}", elderId, reviewStatus);
                return false;
            }

            // 查询老人信息
            ElderBasic elder = baseMapper.selectById(elderId);
            if (elder == null) {
                org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                    .error("未找到对应老人: elderId={}", elderId);
                return false;
            }

            // 更新审核状态
            elder.setReviewStatus(reviewStatus);

            // 添加审核人和审核时间
            org.dromara.common.core.domain.model.LoginUser loginUser = org.dromara.common.satoken.utils.LoginHelper.getLoginUser();
            if (loginUser != null) {
                elder.setReviewedBy(loginUser.getUsername());
            }
            elder.setReviewTime(new java.util.Date());

            boolean result = baseMapper.updateById(elder) > 0;

            if (result) {
                org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                    .info("老人信息审核状态更新成功: elderId={}, newReviewStatus={}", elderId, reviewStatus);
            } else {
                org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                    .error("老人信息审核状态更新失败: elderId={}", elderId);
            }

            return result;
        } catch (Exception e) {
            org.slf4j.LoggerFactory.getLogger(ElderBasicServiceImpl.class)
                .error("老人信息审核操作失败", e);
            return false;
        }
    }
}
